home *** CD-ROM | disk | FTP | other *** search
- Path: newshost.lanl.gov!tanmoy
- From: tanmoy@qcd.lanl.gov (Tanmoy Bhattacharya)
- Newsgroups: comp.lang.c
- Subject: Re: void pointers
- Date: 14 Jan 1996 05:49:57 GMT
- Organization: Los Alamos National Laboratory
- Message-ID: <TANMOY.96Jan13224957@qcd.lanl.gov>
- References: <1996Jan12.133322.1@ccc.govt.nz> <4d8j83$n3@s02.pavilion.co.uk>
- NNTP-Posting-Host: qcd.lanl.gov
- Mime-Version: 1.0
- Content-Type: text
- In-reply-to: AJRobb@pavilion.co.uk's message of Sat, 13 Jan 1996 15:32:15 GMT
-
- --text follows this line--
- In article <4d8j83$n3@s02.pavilion.co.uk> AJRobb@pavilion.co.uk (Andy
- J Robb) writes:
- <snip>
- > void getFence (void **clipPP);
- <snip>
- YourType *clipP; /* set up an unitialized pointer */
- getFence(&clipP); /* initialize it in the functions */
-
- This is wrong (unless YourType is actually void). This is a very
- common misconception however, despite the FAQ: and so I am following
- up. Please read the FAQ before posting.
-
- >2) What is actually going on?
-
- The (void*) type is a dirty catch-all pointer. It can point to
- anything but you must cast it or assign it to something else before
- you use it.
-
- Almost. But this does not mean that void* has the same size and
- representation as every other pointer! Declaring something as void*
- tells the compiler to set aside enough space to record information
- about any kind of data pointer. When you assign some other kind of
- pointer to it, the compiler _converts_ the internal representation of
- that pointer to the `generic' void* format. Similarly, when assigning
- void* to anything else, the compiler converts from the generic format
- to the format for the speicific type in question. Naturally, to do
- this, the compiler needs to know that it is doing a conversion, what
- it is converting from, and what it is converting to.
-
- Now see what happens in the following:
-
- void f(void** x) { *x = 0; }
- void g(void* x) { x = 0; }
- void h(void* x) { double*z=x; *z = 0;}
- int main(void) { int *y; f(&y); g(y); h(y); return 0; } /* Invalid code */
-
- When the compiler is compiling f, it knows that it has to store a null
- pointer into *x. But which representation of the null pointer? The
- answer obviously is the generic `void*' representation.
-
- On the other hand, if the call to f in main would have been valid, *x
- is but y, and the values in y are interpreted to be of type int*. Note
- that f stored the `void*' representation of a null pointer into this
- space: but, for all we know, void* does not even fit into an int*
- variable. And naturally, f could not have stored an int*, because it
- did not _know_ that *x can be an int*!!! So, the standard states that
- the compiler _must_ diagnose this misuse.
-
- Note now the case of g. This call is perfectly valid. This also stores
- the void* representation of the null pointer; but into x --- which
- because of the call by value convention of C, is not the same as y! It
- is only that y is used to initialize a truly independent void*
- variable x, and the format convertion from int* to void* happens
- during this initialization.
-
- The case of h is again different. In this case, the double
- representation of 0 is put into *z, where z is initialized from x
- (thorigh the void* ---> double* format conversion). This is an
- error!!! because x is actually the generic representation of something
- that points to an int, and not something that points to a double. This
- error however does not need to be diagnosed by the compiler: showing
- thus that void* ---> non-void* is a dangerous conversion. In the
- related language C++, this is therefore prohibited in the absence of a
- cast. In C, one chooses ease of use over safety.
-
- In my example, I have shown that I have a pointer to a type
- (YourType). This allows the returned pointer to be used without
- casting. I then passed the address OF this pointer (rather than the
- address held by the pointer) to the function, getFence(). The
- prototype declaration of getFence() will cause an implicit cast to
- (void**) in the call. The function, getFence(), then does its
- business and returns the address of the result in the pointer, clipP.
- It can do this because you gave it the address of clipP.
-
- But as my analysis above demonstrates, the code is wrong.
-
- Cheers
- Tanmoy
- --
- tanmoy@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tanmoy@lanl.gov"(1.218=1242)
- Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544
- Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
- <http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
- internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
- fax: 1 (505) 665 3003 voice: 1 (505) 665 4733 [ Home: 1 (505) 662 5596 ]
-